package com.ebupt.migu.music.pubBroadcast.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.exception.MyException;
import com.ebupt.migu.music.common.exception.StatusEnum;
import com.ebupt.migu.music.common.util.CSVUtils;
import com.ebupt.migu.music.common.util.DateUtil;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.AddActIntoRedisPo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastActivityInfoVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastBannerInfoVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastCustomerFileVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastCustomerInputVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastCustomerTagVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastPlaylistInfoVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.BroadcastRadioInfoVo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.PolicyInfoBo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.PolicyListBo;
import com.ebupt.migu.music.pubBroadcast.entity.policyList.PolicyListPo;
import com.ebupt.migu.music.pubBroadcast.mapper.CreatePolicyMapper;
import com.ebupt.migu.music.pubBroadcast.mapper.PolicyListMapper;
import com.ebupt.migu.music.pubBroadcast.service.PolicyListService;
import com.ebupt.migu.music.pubBroadcast.utils.constant.CommonConstant;
import com.ebupt.migu.music.pubBroadcast.utils.enumeration.BroadcastCustomerTagEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PolicyListServiceImpl implements PolicyListService {

    @Autowired
    private PolicyListMapper policyListMapper;

    @Autowired
    private CreatePolicyMapper createPolicyMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 策略列表
     * @param policyListBo
     * @return
     */
    @Override
        public ResultObject policyList(PolicyListBo policyListBo) {
        Page<PolicyListPo> page = new Page<>(policyListBo.getPage(),policyListBo.getPageSize());
        IPage<PolicyListPo> policyListPoIPage = policyListMapper.policyList(page,policyListBo);
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(policyListPoIPage);
        return res;
    }

    /**
     * 策略查看
     * @param policyInfoBo
     * @return
     */
    @Override
    public ResultObject policyInfo(PolicyInfoBo policyInfoBo) {
        Map<String,Object> resultMap = new HashMap<>();
        //公播平台活动详情
        BroadcastActivityInfoVo broadcastActivityInfoVo = policyListMapper.broadcastActivityInfo(policyInfoBo);
        //公播平台文件导入客群
        BroadcastCustomerFileVo fileVo = policyListMapper.broadcastCustomerFile(policyInfoBo);
        //公播平台手工录入客群
        List<BroadcastCustomerInputVo> broadcastCustomerInputVos = policyListMapper.broadcastCustomerInput(policyInfoBo);
        //音乐馆-banner
        BroadcastBannerInfoVo broadcastBannerInfoVo = policyListMapper.broadcastBannerInfo(policyInfoBo);
        //音乐馆-歌单广场
        BroadcastPlaylistInfoVo broadcastPlaylistInfoVo = policyListMapper.broadcastPlaylistInfo(policyInfoBo);
        //语音播报-语音广场
        BroadcastRadioInfoVo broadcastRadioInfoVo = policyListMapper.broadcastRadioInfo(policyInfoBo);
        resultMap.put("activityInfo",broadcastActivityInfoVo);
        resultMap.put("customerFile",fileVo);
        resultMap.put("customerInput",broadcastCustomerInputVos);
        resultMap.put("bannerInfo",broadcastBannerInfoVo);
        resultMap.put("playlistInfo",broadcastPlaylistInfoVo);
        resultMap.put("radioInfo",broadcastRadioInfoVo);
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(resultMap);
        return res;
    }

    /**
     * 删除
     * @param activityId
     * @return
     */
    @Override
    public ResultObject deletePolicy(String activityId) {
        //查询数据
        PolicyInfoBo policyInfoBo = new PolicyInfoBo();
        policyInfoBo.setActivityId(activityId);
        BroadcastActivityInfoVo broadcastActivityInfoVo = policyListMapper.broadcastActivityInfo(policyInfoBo);
        String activityStatus = broadcastActivityInfoVo.getActivityStatus();
        if (!"0".equals(activityStatus)){
            throw new MyException(StatusEnum.ERROR, "策略不是未开始状态，无法删除！");
        }
        createPolicyMapper.deleteOldPolicyData(activityId);
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        return res;
    }

    /**
     * 暂停
     * @param activityId
     * @return
     */
    @Override
    @Transactional(rollbackFor = MyException.class)
    public ResultObject pausePolicy(String activityId) {
        PolicyInfoBo policyInfoBo = new PolicyInfoBo();
        policyInfoBo.setActivityId(activityId);
        BroadcastActivityInfoVo broadcastActivityInfoVo = policyListMapper.broadcastActivityInfo(policyInfoBo);
        String activityStatus = broadcastActivityInfoVo.getActivityStatus();
        if (!"1".equals(activityStatus)){
            throw new MyException(StatusEnum.ERROR, "策略不是进行中，无法暂停！");
        }
        // 当前时间
        Date now = null;
        try{
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
            now = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
        }catch (Exception e){
            log.error("日期转换失败:"+e.getMessage());
            e.printStackTrace();
            throw new MyException(StatusEnum.ERROR, "日期转换失败:"+e.getMessage());
        }
        //修改公播平台活动状态
        policyListMapper.updatePause(activityId,"1",now);
        //删除redis
        for (int i=1;i<5;i++){
            BroadcastCustomerTagEnum byTagModule = BroadcastCustomerTagEnum.getByTagModule(String.valueOf(i));
            String redisStr = byTagModule.getRedisStr();
            redisTemplate.delete(activityId+"_"+redisStr);
        }
        redisTemplate.delete(activityId+"_"+ CommonConstant.customerFileRedis);
        redisTemplate.delete(activityId+"_"+CommonConstant.customerInputRedis);
        redisTemplate.opsForSet().remove(CommonConstant.allActRedis,activityId);
        redisTemplate.opsForSet().remove(CommonConstant.startActRedis,activityId);
        redisTemplate.delete(activityId+"_"+CommonConstant.actBaseInfo);
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        return res;
    }

    /**
     * 开始
     * @param activityId
     * @return
     */
    @Override
    @Transactional(rollbackFor = MyException.class)
    public ResultObject startPolicy(String activityId) {
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        PolicyInfoBo policyInfoBo = new PolicyInfoBo();
        policyInfoBo.setActivityId(activityId);
        BroadcastActivityInfoVo broadcastActivityInfoVo = policyListMapper.broadcastActivityInfo(policyInfoBo);
        String pause = broadcastActivityInfoVo.getPause();
        if ("0".equals(pause)){
            return res;
        }
        //判断当前公播活动是否结束
        Date endTime = broadcastActivityInfoVo.getEndTime();
        // 当前时间
        Date now = null;
        try{
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
            now = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
        }catch (Exception e){
            log.error("日期转换失败:"+e.getMessage());
            e.printStackTrace();
            throw new MyException(StatusEnum.ERROR, "日期转换失败:"+e.getMessage());
        }
        if (now.getTime()>endTime.getTime()){
            throw new MyException(StatusEnum.ERROR,"策略已结束，无法启动！");
        }
        //修改公播平台活动状态
        policyListMapper.updatePause(activityId,"0",now);
        //添加redis
        addActIntoRedis(activityId);
        return res;
    }


    private void addActIntoRedis(String activityId){
        //客群类型：1-标签客群；2-文件上传【商户ID】；3-手工录入【商户ID】4-全量标签
        AddActIntoRedisPo infoVo = policyListMapper.addActIntoRedis(activityId);
        String customerType = infoVo.getCustomerType();
        PolicyInfoBo policyInfoBo = new PolicyInfoBo();
        policyInfoBo.setActivityId(activityId);
        //用来存储活动有哪些标签模块
        List<String> tagModuleList = new ArrayList<>();
        if ("1".equals(customerType)){
            log.info("addActIntoRedis组装标签客群==="+activityId);
            //查询标签
            List<BroadcastCustomerTagVo> tagVos = policyListMapper.broadcastCustomerTag(activityId);
            for (int i=1;i<=4;i++){
                //标签模块：1-店铺标签；2-音乐馆标签；3-语音播报标签；4-套餐标签；
                String tagModule = String.valueOf(i);
                Optional<BroadcastCustomerTagVo> first = tagVos.stream()
                        .filter(e -> e.getTagModule().equals(tagModule)).findFirst();
                //将公播平台标签客群存到redis
                // public_broadcast_customer_tag表里面的数据
                if (first.isPresent()){
                    tagModuleList.add(tagModule);
                    BroadcastCustomerTagVo broadcastCustomerTagVo = first.get();
                    String tagPath = broadcastCustomerTagVo.getTagPath();
                    BroadcastCustomerTagEnum byTagModule = BroadcastCustomerTagEnum.getByTagModule(broadcastCustomerTagVo.getTagModule());
                    String redisStr = byTagModule.getRedisStr();
                    redisTemplate.opsForSet().add(activityId+"_"+redisStr,tagPath.split(CommonConstant.pubBroadcastSplit));
                }
            }
        }else if ("2".equals(customerType)){
            log.info("addActIntoRedis文件上传【商户ID】==="+activityId);
            //获取用户上传的CSV地址
            BroadcastCustomerFileVo fileVos = policyListMapper.broadcastCustomerFile(policyInfoBo);
            String filePath = fileVos.getFileRename();
            //解析用户上传的CSV文件
            if (!StringUtils.isBlank(filePath)){
                List<String[]> strings = CSVUtils.csvRead(filePath,',');
                if (strings !=null && strings.size()>0){
                    List<String> collect = strings.stream().map(e -> e[0]).collect(Collectors.toList());
                    redisTemplate.opsForSet().add(activityId+"_"+CommonConstant.customerFileRedis,collect.toArray());
                }
            }
        }else if ("3".equals(customerType)){
            log.info("addActIntoRedis手工录入==="+activityId);
            //公播平台手工录入客群
            List<BroadcastCustomerInputVo> inputVo = policyListMapper.broadcastCustomerInput(policyInfoBo);
            if (inputVo !=null && inputVo.size()>0){
                List<String> collect = inputVo.stream().map(e -> e.getStoreId()).collect(Collectors.toList());
                redisTemplate.opsForSet().add(activityId+"_"+CommonConstant.customerInputRedis,collect.toArray());
            }
        }
        infoVo.setTagModuleList(tagModuleList);
        //如果是全量标签，代表这个客群什么活动都参与
        if ("4".equals(customerType)){
            log.info("addActIntoRedis全量标签==="+activityId);
            redisTemplate.opsForSet().add(CommonConstant.allActRedis,activityId);
        }else {
            log.info("addActIntoRedis不是全量活动==="+activityId);
            redisTemplate.opsForSet().add(CommonConstant.startActRedis,activityId);
        }
        //活动基本信息
        redisTemplate.opsForValue().set(activityId+"_"+CommonConstant.actBaseInfo, JSONObject.toJSONString(infoVo));
        log.info("addActIntoRedis获取开启成功:"+activityId);
    }
}
